/// <summary>
// CodeFx.MySqlProviders - .NET Providers for MySql using the framework CodeFx
// Laurent Morisseau
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// Laurent Morisseau
/// </summary>
/// <author><a href="mailto:laurent.morisseau@gmail.com">Laurent Morisseau</a></author>

using System.Web.Security;
using System.Configuration.Provider;
using System.Collections.Specialized;
using System;
using System.Data;
using MySql.Data.MySqlClient;
using System.Configuration;
using System.Diagnostics;
using System.Web;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Web.Configuration;
using System.Text.RegularExpressions;
using CodeFx;
using System.Web.Management;
using System.ComponentModel;

namespace CodeFx.MySqlProviders
{

    public sealed class MySqlMembershipProvider : MembershipProvider
    {

        private string _AppName;
        private bool _EnablePasswordReset;
        private bool _EnablePasswordRetrieval;
        private int _MaxInvalidPasswordAttempts;
        private int _MinRequiredNonalphanumericCharacters;
        private int _MinRequiredPasswordLength;
        private int _PasswordAttemptWindow;
        private MembershipPasswordFormat _PasswordFormat;
        private string _PasswordStrengthRegularExpression;
        private bool _RequiresQuestionAndAnswer;
        private bool _RequiresUniqueEmail;
        private const int PASSWORD_SIZE = 14;


        public override void Initialize(string name, NameValueCollection config)
        {
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }
            if (string.IsNullOrEmpty(name))
            {
                name = "MySqlMembershipProvider";
            }
            if (string.IsNullOrEmpty(config["description"]))
            {
                config.Remove("description");
                config.Add("description", "MembershipSqlProvider_description");
            }
            base.Initialize(name, config);
            this._EnablePasswordRetrieval = Convert.ToBoolean(GetConfigValue(config["enablePasswordRetrieval"], "false"));
            this._EnablePasswordReset = Convert.ToBoolean(GetConfigValue(config["enablePasswordReset"], "true"));
            this._RequiresQuestionAndAnswer = Convert.ToBoolean(GetConfigValue(config["requiresQuestionAndAnswer"], "true"));
            this._RequiresUniqueEmail = Convert.ToBoolean(GetConfigValue(config["requiresUniqueEmail"], "true"));
            this._MaxInvalidPasswordAttempts = Convert.ToInt32(GetConfigValue(config["maxInvalidPasswordAttempts"], "5"));
            this._PasswordAttemptWindow = Convert.ToInt32(GetConfigValue(config["passwordAttemptWindow"], "10"));
            this._MinRequiredPasswordLength = Convert.ToInt32(GetConfigValue(config["minRequiredPasswordLength"], "7"));
            this._MinRequiredNonalphanumericCharacters = Convert.ToInt32(GetConfigValue(config["minRequiredNonalphanumericCharacters"], "1"));
            this._PasswordStrengthRegularExpression = config["passwordStrengthRegularExpression"];
            if (this._PasswordStrengthRegularExpression != null)
            {
                this._PasswordStrengthRegularExpression = this._PasswordStrengthRegularExpression.Trim();
                if (this._PasswordStrengthRegularExpression.Length == 0)
                {
                    goto Label_016C;
                }
                try
                {
                    new Regex(this._PasswordStrengthRegularExpression);
                    goto Label_016C;
                }
                catch (ArgumentException exception1)
                {
                    throw new ProviderException(exception1.Message, exception1);
                }
            }
            this._PasswordStrengthRegularExpression = string.Empty;
        Label_016C:
            if (this._MinRequiredNonalphanumericCharacters > this._MinRequiredPasswordLength)
            {
                throw new HttpException("MinRequiredNonalphanumericCharacters_can_not_be_more_than_MinRequiredPasswordLength");
            }
            this._AppName = config["applicationName"];
            if (string.IsNullOrEmpty(this._AppName))
            {
                throw new ProviderException("Provider_application_name_not_null");
            }
            if (this._AppName.Length > 0x100)
            {
                throw new ProviderException("Provider_application_name_too_long");
            }
            string text1 = config["passwordFormat"];
            if (text1 == null)
            {
                text1 = "Hashed";
            }
            string text4 = text1;
            if (text4 != null)
            {
                if (text4 == "Clear")
                {
                    this._PasswordFormat = MembershipPasswordFormat.Clear;
                    goto Label_025C;
                }
                if (text4 == "Encrypted")
                {
                    this._PasswordFormat = MembershipPasswordFormat.Encrypted;
                    goto Label_025C;
                }
                if (text4 == "Hashed")
                {
                    this._PasswordFormat = MembershipPasswordFormat.Hashed;
                    goto Label_025C;
                }
            }
            throw new ProviderException("Provider_bad_password_format");
        Label_025C:
            if ((this.PasswordFormat == MembershipPasswordFormat.Hashed) && this.EnablePasswordRetrieval)
            {
                throw new ProviderException("Provider_can_not_retrieve_hashed_password");
            }
            string text2 = config["connectionStringName"];
            if ((text2 == null) || (text2.Length < 1))
            {
                throw new ProviderException("Connection_name_not_specified");
            }
            /// ConnectionString
            ConnectionString.Current.ConnectionStringName = config["connectionStringName"];
           
            config.Remove("connectionStringName");
            config.Remove("enablePasswordRetrieval");
            config.Remove("enablePasswordReset");
            config.Remove("requiresQuestionAndAnswer");
            config.Remove("applicationName");
            config.Remove("requiresUniqueEmail");
            config.Remove("maxInvalidPasswordAttempts");
            config.Remove("passwordAttemptWindow");
            config.Remove("commandTimeout");
            config.Remove("passwordFormat");
            config.Remove("name");
            config.Remove("minRequiredPasswordLength");
            config.Remove("minRequiredNonalphanumericCharacters");
            config.Remove("passwordStrengthRegularExpression");
            if (config.Count > 0)
            {
                string text3 = config.GetKey(0);
                if (!string.IsNullOrEmpty(text3))
                {
                    throw new ProviderException("Provider_unrecognized_attribute");
                }
            }

        }
        
        private string GetConfigValue(string configValue, string defaultValue)
        {
            if (String.IsNullOrEmpty(configValue))
                return defaultValue;

            return configValue;
        }


        public override string ApplicationName
        {
            get { return _AppName; }
            set { _AppName = value; }
        }

        public override bool EnablePasswordReset
        {
            get { return _EnablePasswordReset; }
        }


        public override bool EnablePasswordRetrieval
        {
            get { return _EnablePasswordRetrieval; }
        }


        public override bool RequiresQuestionAndAnswer
        {
            get { return _RequiresQuestionAndAnswer; }
        }


        public override bool RequiresUniqueEmail
        {
            get { return _RequiresUniqueEmail; }
        }


        public override int MaxInvalidPasswordAttempts
        {
            get { return _MaxInvalidPasswordAttempts; }
        }


        public override int PasswordAttemptWindow
        {
            get { return _PasswordAttemptWindow; }
        }


        public override MembershipPasswordFormat PasswordFormat
        {
            get { return _PasswordFormat; }
        }

        private int _MinRequiredNonAlphanumericCharacters;

        public override int MinRequiredNonAlphanumericCharacters
        {
            get { return _MinRequiredNonAlphanumericCharacters; }
        }

        
        public override int MinRequiredPasswordLength
        {
            get { return _MinRequiredPasswordLength; }
        }

        
        public override string PasswordStrengthRegularExpression
        {
            get { return _PasswordStrengthRegularExpression; }
        }



        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        {

            int num1;
            SecUtility.CheckParameter(ref username, true, true, true, 0x100, "username");
            SecUtility.CheckParameter(ref oldPassword, true, true, false, 0x80, "oldPassword");
            SecUtility.CheckParameter(ref newPassword, true, true, false, 0x80, "newPassword");
            string text1 = null;
            if (!this.CheckPassword(username, oldPassword, false, false, out text1, out num1))
            {
                return false;
            }
            if (newPassword.Length < this.MinRequiredPasswordLength)
            {
                throw new ArgumentException("Password_too_short");
            }
            int num3 = 0;
            for (int num4 = 0; num4 < newPassword.Length; num4++)
            {
                if (!char.IsLetterOrDigit(newPassword, num4))
                {
                    num3++;
                }
            }
            if (num3 < this.MinRequiredNonAlphanumericCharacters)
            {
                throw new ArgumentException("Password_need_more_non_alpha_numeric_chars");
            }
            if ((this.PasswordStrengthRegularExpression.Length > 0) && !Regex.IsMatch(newPassword, this.PasswordStrengthRegularExpression))
            {
                throw new ArgumentException("Password_does_not_match_regular_expression");
            }
            string text2 = SecUtility.EncodePassword(newPassword, num1, text1);
            if (text2.Length > 0x80)
            {
                throw new ArgumentException("Membership_password_too_long");
            }
            ValidatePasswordEventArgs args1 = new ValidatePasswordEventArgs(username, newPassword, false);
            this.OnValidatingPassword(args1);
            if (args1.Cancel)
            {
                if (args1.FailureInformation != null)
                {
                    throw args1.FailureInformation;
                }
                throw new ArgumentException("Membership_Custom_Password_Validation_Failure");
            }
            uint userid = GetUserId(username);
            if (userid == 0)
            {
                string text3 = SecUtility.GetExceptionText(1);
                if (this.IsStatusDueToBadPassword(1))
                {
                    throw new MembershipPasswordException(text3);
                }
                throw new ProviderException(text3);
            }
            Aspnet_membershipDTO.SetPassword(text2, num1.ToString(), text1, userid);
            return true;

        }

        public override bool ChangePasswordQuestionAndAnswer(string username,
                      string password,
                      string newPasswordQuestion,
                      string newPasswordAnswer)
        {
            string text1;
            int num1;
            string text2;
            SecUtility.CheckParameter(ref username, true, true, true, 0x100, "username");
            SecUtility.CheckParameter(ref password, true, true, false, 0x80, "password");
            if (!this.CheckPassword(username, password, false, false, out text1, out num1))
            {
                return false;
            }
            SecUtility.CheckParameter(ref newPasswordQuestion, this.RequiresQuestionAndAnswer, this.RequiresQuestionAndAnswer, false, 0x100, "newPasswordQuestion");
            if (newPasswordAnswer != null)
            {
                newPasswordAnswer = newPasswordAnswer.Trim();
            }
            SecUtility.CheckParameter(ref newPasswordAnswer, this.RequiresQuestionAndAnswer, this.RequiresQuestionAndAnswer, false, 0x80, "newPasswordAnswer");
            if (!string.IsNullOrEmpty(newPasswordAnswer))
            {
                text2 = SecUtility.EncodePassword(newPasswordAnswer.ToLower(CultureInfo.InvariantCulture), num1, text1);
            }
            else
            {
                text2 = newPasswordAnswer;
            }
            SecUtility.CheckParameter(ref text2, this.RequiresQuestionAndAnswer, this.RequiresQuestionAndAnswer, false, 0x80, "newPasswordAnswer");
            uint userid = GetUserId(username);
            if (userid == 0)
            {
                throw new ProviderException(SecUtility.GetExceptionText(1));
            }
            Aspnet_membershipDTO.ChangePasswordQuestionAndAnswer(newPasswordQuestion, text2, userid);

            return true;

        }


        public override MembershipUser CreateUser(string username,
                 string password,
                 string email,
                 string passwordQuestion,
                 string passwordAnswer,
                 bool isApproved,
                 object providerUserKey,
                 out MembershipCreateStatus status)
        {

            string text3;
            if (!SecUtility.ValidateParameter(ref password, true, true, false, 0x80))
            {
                status = MembershipCreateStatus.InvalidPassword;
                return null;
            }
            string text1 = SecUtility.GenerateSalt();
            string text2 = SecUtility.EncodePassword(password, (int)this._PasswordFormat, text1);
            if (text2.Length > 0x80)
            {
                status = MembershipCreateStatus.InvalidPassword;
                return null;
            }
            if (passwordAnswer != null)
            {
                passwordAnswer = passwordAnswer.Trim();
            }
            if (!string.IsNullOrEmpty(passwordAnswer))
            {
                if (passwordAnswer.Length > 0x80)
                {
                    status = MembershipCreateStatus.InvalidAnswer;
                    return null;
                }
                text3 = SecUtility.EncodePassword(passwordAnswer.ToLower(CultureInfo.InvariantCulture), (int)this._PasswordFormat, text1);
            }
            else
            {
                text3 = passwordAnswer;
            }
            if (!SecUtility.ValidateParameter(ref text3, this.RequiresQuestionAndAnswer, true, false, 0x80))
            {
                status = MembershipCreateStatus.InvalidAnswer;
                return null;
            }
            if (!SecUtility.ValidateParameter(ref username, true, true, true, 0x100))
            {
                status = MembershipCreateStatus.InvalidUserName;
                return null;
            }
            if (!SecUtility.ValidateParameter(ref email, this.RequiresUniqueEmail, this.RequiresUniqueEmail, false, 0x100))
            {
                status = MembershipCreateStatus.InvalidEmail;
                return null;
            }
            if (!SecUtility.ValidateParameter(ref passwordQuestion, this.RequiresQuestionAndAnswer, true, false, 0x100))
            {
                status = MembershipCreateStatus.InvalidQuestion;
                return null;
            }
            if ((providerUserKey != null) && !(providerUserKey is Guid))
            {
                status = MembershipCreateStatus.InvalidProviderUserKey;
                return null;
            }
            if (password.Length < this.MinRequiredPasswordLength)
            {
                status = MembershipCreateStatus.InvalidPassword;
                return null;
            }
            int num1 = 0;
            for (int num2 = 0; num2 < password.Length; num2++)
            {
                if (!char.IsLetterOrDigit(password, num2))
                {
                    num1++;
                }
            }
            if (num1 < this.MinRequiredNonAlphanumericCharacters)
            {
                status = MembershipCreateStatus.InvalidPassword;
                return null;
            }
            if ((this.PasswordStrengthRegularExpression.Length > 0) && !Regex.IsMatch(password, this.PasswordStrengthRegularExpression))
            {
                status = MembershipCreateStatus.InvalidPassword;
                return null;
            }
            ValidatePasswordEventArgs args1 = new ValidatePasswordEventArgs(username, password, true);
            this.OnValidatingPassword(args1);
            if (args1.Cancel)
            {
                status = MembershipCreateStatus.InvalidPassword;
                return null;
            }
            DateTime time1 = RoundToSeconds(DateTime.UtcNow);
            int num3 = 0;
            uint appid = ApplicationId;
            if (appid == 0)
            {
                Aspnet_applicationsDAL newApp = new Aspnet_applicationsDAL();
                newApp.ApplicationName = this.ApplicationName;
                Aspnet_applicationsDTO.Insert(newApp);
                appid = Aspnet_applicationsDTO.GetLastId(this.ApplicationName);
            }
            Aspnet_usersDAL user = Aspnet_usersDTO.SelectByFk_ApplicationId_UserNameWithPersistance(appid, username);
            uint userid = 0;
            if (user != null)
            {
                userid = user.UserId;
                if ((providerUserKey != null) && (Convert.ToUInt32(providerUserKey) != userid))
                {
                    num3 = 6;
                    goto Label_016C;
                }
            }
            else
            {
                user = new Aspnet_usersDAL();
                user.UserName = username;
                user.ApplicationId = appid;
                user.IsAnonymous = 0;
                user.LastActivityDate = DateTime.UtcNow;
                Aspnet_usersDTO.Insert(user);
                userid = Aspnet_usersDTO.GetLastId(user);
                if (userid == 0)
                {
                    num3 = 10;
                    goto Label_016C;
                }
            }
            if (Aspnet_membershipDTO.Exist(userid))
            {
                num3 = 6;
                goto Label_016C;
            }

            if (Aspnet_membershipDTO.Exist(appid, email))
            {
                num3 = 7;
                goto Label_016C;
            }
            Aspnet_membershipDAL member = new Aspnet_membershipDAL();
            member.ApplicationId = appid;
            member.CreateDate = time1;
            member.Email = email;
            member.FailedPasswordAnswerAttemptCount = 0;
            member.FailedPasswordAnswerAttemptWindowStart = DateTime.MinValue;
            member.FailedPasswordAttemptCount = 0;
            member.FailedPasswordAttemptWindowStart = DateTime.MinValue;
            member.IsApproved = ConvertHelper.BoolToByte(isApproved);
            member.IsLockedOut = 0;
            member.LastLockedOutDate = DateTime.MinValue;
            member.LastLoginDate = time1;
            member.LastPasswordChangedDate = time1;
            member.Password = text2;
            member.PasswordAnswer = text3;
            member.PasswordFormat = Convert.ToByte(this.PasswordFormat);
            member.PasswordQuestion = passwordQuestion;
            member.PasswordSalt = text1;
            member.UserId = userid;
            Aspnet_membershipDTO.Insert(member);

        Label_016C:
            if ((num3 < 0) || (num3 > 11))
            {
                num3 = 11;
            }
            status = (MembershipCreateStatus)num3;
            if (num3 != 0)
            {
                return null;
            }
            providerUserKey = Guid.NewGuid();
            time1 = time1.ToLocalTime();
            return new MembershipUser(this.Name, username, providerUserKey, email, passwordQuestion, null, isApproved, false, time1, time1, time1, time1, new DateTime(0x6da, 1, 1));


        }

        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            SecUtility.CheckParameter(ref username, true, true, true, 0x100, "username");
            uint appid = ApplicationId;
            if (appid == 0)
                return false;
            uint userid = GetUserId(username);
            if (userid == 0)
                return false;
            Aspnet_membershipDAL member = new Aspnet_membershipDAL();
            member.UserId = userid;
            Aspnet_membershipDTO.DeleteByFk_UserId(member);
            if (deleteAllRelatedData)
            {
                Aspnet_usersinrolesDAL usersinrole = new Aspnet_usersinrolesDAL();
                usersinrole.UserId = userid;
                Aspnet_usersinrolesDTO.DeleteByFk_UserId(usersinrole);

                Aspnet_profileDAL profile = new Aspnet_profileDAL();
                profile.UserId = userid;
                Aspnet_profileDTO.DeleteByFk_UserId(profile);

                Aspnet_usersDAL user = new Aspnet_usersDAL();
                user.UserId = userid;
                Aspnet_usersDTO.Delete(user);
            }
            return true;
        }

        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        {
            if (pageIndex < 0)
            {
                throw new ArgumentException("PageIndex_bad");
            }
            if (pageSize < 1)
            {
                throw new ArgumentException("PageSize_bad");
            }
            long num1 = ((pageIndex * pageSize) + pageSize) - 1;
            if (num1 > 0x7fffffff)
            {
                throw new ArgumentException("PageIndex_PageSize_bad");
            }
            totalRecords = 0;
            uint appid = ApplicationId;
            if (appid == 0)
                return null;
            object obj1 = Aspnet_membershipDTO.CountAllUsers(appid);
            if (obj1 == null)
            {
                return null;
            }
            totalRecords = Convert.ToInt32(obj1);

            return Aspnet_membershipDTO.GetAllUsers(this.Name, appid, pageIndex * pageSize, pageSize);
        }


        public override int GetNumberOfUsersOnline()
        {
            object count = Aspnet_membershipDTO.GetNumberOfUsersOnline(ApplicationId, DateTime.UtcNow.AddMinutes(-Membership.UserIsOnlineTimeWindow));
            if (count == null)
            {
                return 0;
            }
            return Convert.ToInt32(count);

        }

        public override string GetPassword(string username, string passwordAnswer)
         {
            if (!this.EnablePasswordRetrieval)
            {
                throw new NotSupportedException("Membership_PasswordRetrieval_not_supported");
            }
            SecUtility.CheckParameter(ref username, true, true, true, 0x100, "username");
            string text1 = this.GetEncodedPasswordAnswer(username, passwordAnswer);
            SecUtility.CheckParameter(ref text1, this.RequiresQuestionAndAnswer, this.RequiresQuestionAndAnswer, false, 0x80, "passwordAnswer");
            int num1 = 0;
            int num2 = 0;
            string text3 = this.GetPasswordFromDB(username, text1, this.RequiresQuestionAndAnswer, out num1, out num2);
            if (text3 == null)
            {
                string text2 = SecUtility.GetExceptionText(num2);
                if (this.IsStatusDueToBadPassword(num2))
                {
                    throw new MembershipPasswordException(text2);
                }
                throw new ProviderException(text2);
            }
            return SecUtility.UnEncodePassword(text3, num1);

        }

        public override MembershipUser GetUser(string username, bool userIsOnline)
        {
            SecUtility.CheckParameter(ref username, true, false, true, 0x100, "username");

            uint userid = GetUserId(username);
            if (userid == 0)
                return null;
            return GetUser((object)userid, userIsOnline);
        }

        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            if (providerUserKey == null)
            {
                throw new ArgumentNullException("providerUserKey");
            }
            if (!(providerUserKey is uint))
            {
                throw new ArgumentException("Membership_InvalidProviderUserKey");
            }
            uint userid = (uint)providerUserKey;
            Aspnet_membershipDAL member = Aspnet_membershipDTO.Select(userid);
            Aspnet_usersDAL user = Aspnet_usersDTO.Select(userid);
            if (userIsOnline)
            {
                Aspnet_usersDTO.Update_LastActivityDateWithPersistance(user.UserId, user.UserName  );
                user.LastActivityDate = DateTime.UtcNow;
            }
            return new MembershipUser(this.Name, user.UserName, userid, member.Email, member.PasswordQuestion,
                member.Comment, ConvertHelper.ByteToBool(member.IsApproved), ConvertHelper.ByteToBool(member.IsLockedOut), member.CreateDate,
                member.LastLoginDate, user.LastActivityDate, member.LastPasswordChangedDate, member.LastLockedOutDate);

        }

        public override bool UnlockUser(string username)
        {
            SecUtility.CheckParameter(ref username, true, true, true, 0x100, "username");

            Aspnet_membershipDAL member = Aspnet_membershipDTO.SelectByFk_ApplicationId_UserName(ApplicationId, username);
            if (member != null)
            {
                member.IsLockedOut = 0;
                member.FailedPasswordAttemptCount = 0;
                member.FailedPasswordAttemptWindowStart = DateTime.MinValue;
                member.FailedPasswordAnswerAttemptCount = 0;
                member.FailedPasswordAnswerAttemptWindowStart = DateTime.MinValue;
                member.LastLockedOutDate = DateTime.MinValue;
                Aspnet_membershipDTO.Update(member);
                return true;
            }
            return false;

        }

        public override string GetUserNameByEmail(string email)
        {
            SecUtility.CheckParameter(ref email, false, false, false, 0x100, "email");
            
            return Aspnet_membershipDTO.GetUserNameByEmail(ApplicationId, email);
                }

        public override string ResetPassword(string username, string passwordAnswer)

        {
            string text1;
            int num1;
            string text2;
            int num2;
            int num3;
            int num4;
            bool flag1;
            DateTime time1;
            DateTime time2;
            if (!this.EnablePasswordReset)
            {
                throw new NotSupportedException("Not_configured_to_support_password_resets");
            }
            SecUtility.CheckParameter(ref username, true, true, true, 0x100, "username");
            this.GetPasswordWithFormat(username, false, out num2, out text2, out num1, out text1, out num3, out num4, out flag1, out time1, out time2);
            if (num2 == 0)
            {
                string text3;
                if (passwordAnswer != null)
                {
                    passwordAnswer = passwordAnswer.Trim();
                }
                if (!string.IsNullOrEmpty(passwordAnswer))
                {
                    text3 = SecUtility.EncodePassword(passwordAnswer.ToLower(CultureInfo.InvariantCulture), num1, text1);
                }
                else
                {
                    text3 = passwordAnswer;
                }
                SecUtility.CheckParameter(ref text3, this.RequiresQuestionAndAnswer, this.RequiresQuestionAndAnswer, false, 0x80, "passwordAnswer");
                string text4 = this.GeneratePassword();
                ValidatePasswordEventArgs args1 = new ValidatePasswordEventArgs(username, text4, false);
                this.OnValidatingPassword(args1);
                DateTime dateutc = DateTime.UtcNow;
                if (args1.Cancel)
                {
                    if (args1.FailureInformation != null)
                    {
                        throw args1.FailureInformation;
                    }
                    throw new ProviderException("Membership_Custom_Password_Validation_Failure");
                }
                Aspnet_membershipDAL member = Aspnet_membershipDTO.SelectByFk_ApplicationId_UserName(ApplicationId, username);
                if (member == null)
                {
                    num2 = 1;
                    goto Label_016C;
                }
                if (member.IsLockedOut == 1)
                {
                    num2 = 99;
                    goto Label_016C;
                }
                if ((!this.RequiresQuestionAndAnswer) || (string.Equals(member.PasswordAnswer, text3, StringComparison.InvariantCultureIgnoreCase)))
                {
                    member.Password = SecUtility.EncodePassword(text4, num1, text1);
                    member.LastPasswordChangedDate = dateutc;
                    member.PasswordFormat = Convert.ToByte(num1);
                    member.PasswordSalt = text1;
                    member.FailedPasswordAnswerAttemptCount = 0;
                    member.FailedPasswordAnswerAttemptWindowStart = DateTime.MinValue;
                    Aspnet_membershipDTO.Update(member);
                }
                else if (!string.IsNullOrEmpty(text3))
                {
                    if (dateutc > member.FailedPasswordAnswerAttemptWindowStart.AddMinutes(this.PasswordAttemptWindow))
                    {
                        member.FailedPasswordAnswerAttemptWindowStart = dateutc;
                        member.FailedPasswordAnswerAttemptCount = 1;
                    }
                    else
                    {
                        member.FailedPasswordAnswerAttemptWindowStart = dateutc;
                        member.FailedPasswordAnswerAttemptCount += 1;
                    }

                    if (member.FailedPasswordAnswerAttemptCount >= this.MaxInvalidPasswordAttempts)
                    {
                        member.IsLockedOut = 1;
                        member.LastLockedOutDate = dateutc;
                    }
                    num2 = 3;
                    Aspnet_membershipDTO.Update(member);
                }
                return text4;
            }
            else
            {
                goto Label_016C;
            }
        Label_016C:
            string text5 = SecUtility.GetExceptionText(num2);
            if (this.IsStatusDueToBadPassword(num2))
            {
                throw new MembershipPasswordException(text5);
            }
            throw new ProviderException(text5);
        }

        public override void UpdateUser(MembershipUser user)
        {
            if (user == null)
            {
                throw new ArgumentNullException("user");
            }
            string username = user.UserName;
            SecUtility.CheckParameter(ref username, true, true, true, 0x100, "UserName");
            string text1 = user.Email;
            SecUtility.CheckParameter(ref text1, this.RequiresUniqueEmail, this.RequiresUniqueEmail, false, 0x100, "Email");
            user.Email = text1;
            uint userid = GetUserId(username);
            if (userid == 0)
            {
                throw new ProviderException(SecUtility.GetExceptionText(1));
            }
            if (this.RequiresUniqueEmail && Aspnet_membershipDTO.ExistMultipleEmail(ApplicationId, userid,text1))
            {
                throw new ProviderException(SecUtility.GetExceptionText(7));
            }
            Aspnet_usersDAL userdal = new Aspnet_usersDAL();
            userdal.UserId = userid;
            Aspnet_usersDTO.Update_LastActivityDateWithPersistance(userdal.UserId, username  );
            Aspnet_membershipDAL member = Aspnet_membershipDTO.Select(userid);
            member.Email = user.Email;
            member.Comment = user.Comment;
            member.IsApproved = ConvertHelper.BoolToByte(user.IsApproved) ;
            member.LastLoginDate = user.LastLoginDate.ToUniversalTime();
            Aspnet_membershipDTO.Update(member);

        }

        private uint ApplicationId
        {
            get
            {
                return Aspnet_applicationsDTO.GetApplicationId(_AppName);
            }
        }

        private uint GetUserId(string username)
        {
            return Aspnet_usersDTO.GetUserId(username, ApplicationId);
        }

        public override bool ValidateUser(string username, string password)
        {
            bool isValid = false;
            Aspnet_membershipDAL member = Aspnet_membershipDTO.SelectByFk_ApplicationId_UserName(ApplicationId, username);
            if (member == null)
                return false;


            bool isApproved = ConvertHelper.ByteToBool(member.IsApproved);
            string pwd = member.Password ;

            if (CheckPassword(password, pwd))
            {
                if (isApproved)
                {
                    isValid = true;
                    Aspnet_membershipDTO.Update_LastLoginDate(member);
                    Aspnet_usersDTO.Update_LastActivityDateWithPersistance(member.UserId, username );
                }
            }
            else
            {
                DateTime dateutc = DateTime.UtcNow ;
                if (dateutc > member.FailedPasswordAnswerAttemptWindowStart.AddMinutes(this.PasswordAttemptWindow))
                {
                    member.FailedPasswordAnswerAttemptWindowStart = dateutc;
                    member.FailedPasswordAnswerAttemptCount = 1;
                }
                else
                {
                    member.FailedPasswordAnswerAttemptWindowStart = dateutc;
                    member.FailedPasswordAnswerAttemptCount += 1;
                }

                if (member.FailedPasswordAnswerAttemptCount >= this.MaxInvalidPasswordAttempts)
                {
                    member.IsLockedOut = 1;
                    member.LastLockedOutDate = dateutc;
                }
                Aspnet_membershipDTO.Update(member);
            }

            return isValid;
            
        }


        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            SecUtility.CheckParameter(ref usernameToMatch, true, true, false, 0x100, "usernameToMatch");
            if (pageIndex < 0)
            {
                throw new ArgumentException("PageIndex_bad");
            }
            if (pageSize < 1)
            {
                throw new ArgumentException("PageSize_bad");
            }
            long num1 = ((pageIndex * pageSize) + pageSize) - 1;
            if (num1 > 0x7fffffff)
            {
                throw new ArgumentException("PageIndex_PageSize_bad");
            }
            uint appid = ApplicationId;
            if (appid==0)
            {
                totalRecords = 0;
                return null;
            }
            object count = Aspnet_membershipDTO.CountAllUsers(appid, usernameToMatch);
            if (count == null)
            {
                totalRecords = 0;
            }
            totalRecords =  Convert.ToInt32(count);
            return Aspnet_membershipDTO.GetAllUsers(this.Name, appid, usernameToMatch, pageIndex * pageSize, pageSize);
            
        }

       public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
       {
           SecUtility.CheckParameter(ref emailToMatch, false, false, false, 0x100, "emailToMatch");
           if (pageIndex < 0)
           {
               throw new ArgumentException("PageIndex_bad");
           }
           if (pageSize < 1)
           {
               throw new ArgumentException("PageSize_bad");
           }
           long num1 = ((pageIndex * pageSize) + pageSize) - 1;
           if (num1 > 0x7fffffff)
           {
               throw new ArgumentException("PageIndex_PageSize_bad");
           }

           uint appid = ApplicationId;
           if (appid == 0)
           {
               totalRecords = 0;
               return null;
           }
           object count = Aspnet_membershipDTO.CountAllUsersByEmail(appid, emailToMatch);
           if (count == null)
           {
               totalRecords = 0;
           }
           totalRecords = Convert.ToInt32(count);
           return Aspnet_membershipDTO.GetAllUsersByEmail(this.Name, appid, emailToMatch, pageIndex * pageSize, pageSize);
        }

        private string GetEncodedPasswordAnswer(string username, string passwordAnswer)
        {
            if (passwordAnswer != null)
            {
                passwordAnswer = passwordAnswer.Trim();
            }
            if (!string.IsNullOrEmpty(passwordAnswer))
            {
                int num1;
                int num2;
                int num3;
                int num4;
                string text1;
                string text2;
                bool flag1;
                DateTime time1;
                DateTime time2;
                this.GetPasswordWithFormat(username, false, out num1, out text1, out num2, out text2, out num3, out num4, out flag1, out time1, out time2);
                if (num1 != 0)
                {
                    throw new ProviderException(SecUtility.GetExceptionText(num1));
                }
                return SecUtility.EncodePassword(passwordAnswer.ToLower(CultureInfo.InvariantCulture), num2, text2);
            }
            return passwordAnswer;
        }

        private void GetPasswordWithFormat(string username, bool updateLastLoginActivityDate, out int status, out string password, out int passwordFormat, out string passwordSalt, out int failedPasswordAttemptCount, out int failedPasswordAnswerAttemptCount, out bool isApproved, out DateTime lastLoginDate, out DateTime lastActivityDate)
        {
            uint userid = this.GetUserId(username);
            if (userid == 0)
            {
                status = 1;
                password = null;
                passwordFormat = 0;
                passwordSalt = null;
                failedPasswordAttemptCount = 0;
                failedPasswordAnswerAttemptCount = 0;
                isApproved = false;
                lastLoginDate = DateTime.UtcNow;
                lastActivityDate = DateTime.UtcNow;
                return;
            }
            Aspnet_membershipDAL member = Aspnet_membershipDTO.Select(userid);
            password = member.Password;
            passwordFormat = member.PasswordFormat;
            passwordSalt = member.PasswordSalt;
            failedPasswordAttemptCount = Convert.ToInt32(member.FailedPasswordAttemptCount);
            failedPasswordAnswerAttemptCount = Convert.ToInt32(member.FailedPasswordAnswerAttemptCount);
            isApproved = ConvertHelper.ByteToBool(member.IsApproved);
            lastLoginDate = member.LastLoginDate;

            Aspnet_usersDAL user = Aspnet_usersDTO.Select(userid);
            lastActivityDate = user.LastActivityDate;

            if (ConvertHelper.ByteToBool(member.IsLockedOut))
            {
                status = 99;
                return;
            }

            if (updateLastLoginActivityDate && ConvertHelper.ByteToBool(member.IsApproved))
            {
                Aspnet_usersDTO.Update_LastActivityDateWithPersistance(user.UserId, username  );
                Aspnet_membershipDTO.Update_LastLoginDate(member);
            }
            status = 0;
        }
        private string GetPasswordFromDB(string username, string passwordAnswer, bool requiresQuestionAndAnswer, out int passwordFormat, out int status)
        {
            status = 0;
            uint userid = this.GetUserId(username);
            if (userid == 0)
            {
                passwordFormat = 0;
                status = 1;
                return (string)null;
            }
            DateTime datetimeuct = DateTime.UtcNow;
            Aspnet_membershipDAL member = Aspnet_membershipDTO.Select(userid);
            passwordFormat = member.PasswordFormat;

            if (!string.IsNullOrEmpty(passwordAnswer))
            {
                if (string.IsNullOrEmpty(member.PasswordAnswer) ||
                    (!string.Equals(passwordAnswer, member.PasswordAnswer, StringComparison.InvariantCultureIgnoreCase)))
                {
                    DateTime dateattemp = member.FailedPasswordAnswerAttemptWindowStart.AddMinutes(this.PasswordAttemptWindow);
                    if (datetimeuct > dateattemp)
                    {
                        member.FailedPasswordAnswerAttemptWindowStart = datetimeuct;
                        member.FailedPasswordAnswerAttemptCount = 1;
                    }
                    else
                    {
                        member.FailedPasswordAnswerAttemptCount += 1;
                        member.FailedPasswordAnswerAttemptWindowStart = datetimeuct;
                    }
                    if (member.FailedPasswordAnswerAttemptCount >= this.MaxInvalidPasswordAttempts)
                    {
                        member.IsLockedOut = 1;
                        member.LastLockedOutDate = datetimeuct;
                    }
                    status = 3;
                }
                else if (member.FailedPasswordAnswerAttemptCount > 0)
                {
                    member.FailedPasswordAnswerAttemptCount = 0;
                    member.FailedPasswordAnswerAttemptWindowStart = DateTime.MinValue;
                }
                Aspnet_membershipDTO.Update(member);
            }
            return member.Password;

        }
        private bool IsStatusDueToBadPassword(int status)
        {
            if ((status >= 2) && (status <= 6))
            {
                return true;
            }
            return (status == 0x63);
        }

        public string GeneratePassword()
        {
            return Membership.GeneratePassword((this.MinRequiredPasswordLength < 14) ? 14 : this.MinRequiredPasswordLength, this.MinRequiredNonAlphanumericCharacters);
        }

        private bool CheckPassword(string password, string dbpassword)
        {
            string pass1 = password;
            string pass2 = dbpassword;

            switch (PasswordFormat)
            {
                case MembershipPasswordFormat.Encrypted:
                    pass2 = SecUtility.UnEncodePassword(dbpassword, PasswordFormat);
                    break;
                case MembershipPasswordFormat.Hashed:
                    pass1 = SecUtility.EncodePassword(password, PasswordFormat);
                    break;
                default:
                    break;
            }

            if (pass1 == pass2)
            {
                return true;
            }

            return false;
        }

        private bool CheckPassword(string username, string password, bool updateLastLoginActivityDate, bool failIfNotApproved)
        {
            string text1;
            int num1;
            return this.CheckPassword(username, password, updateLastLoginActivityDate, failIfNotApproved, out text1, out num1);
        }
        
        private bool CheckPassword(string username, string password, bool updateLastLoginActivityDate, bool failIfNotApproved, out string salt, out int passwordFormat)
        {
            string text1;
            int num1;
            int num2;
            int num3;
            bool flag2;
            DateTime time1;
            DateTime time2;
            this.GetPasswordWithFormat(username, updateLastLoginActivityDate, out num1, out text1, out passwordFormat, out salt, out num2, out num3, out flag2, out time1, out time2);
            if (num1 != 0)
            {
                return false;
            }
            if (!flag2 && failIfNotApproved)
            {
                return false;
            }
            string text2 = SecUtility.EncodePassword(password, passwordFormat, salt);
            bool flag1 = text1.Equals(text2);
            if ((flag1 && (num2 == 0)) && (num3 == 0))
            {
                return true;
            }
            Aspnet_membershipDAL member = Aspnet_membershipDTO.SelectByFk_ApplicationId_UserName(ApplicationId, username);
            if (member == null)
                return false;
            if (ConvertHelper.ByteToBool(member.IsLockedOut))
                return false;
            if (flag1)
            {
                DateTime datetimeutc = DateTime.UtcNow;
                if ( datetimeutc> member.FailedPasswordAttemptWindowStart.AddMinutes( this.PasswordAttemptWindow ) )
                {
                    member.FailedPasswordAttemptWindowStart = datetimeutc;
                    member.FailedPasswordAttemptCount = 1;
                }
                else
                {
                    member.FailedPasswordAttemptWindowStart = datetimeutc;
                    member.FailedPasswordAttemptCount += 1;
                }

                if ( member.FailedPasswordAttemptCount >= this.MaxInvalidPasswordAttempts )
                {
                    member.IsLockedOut = 1;
                    member.LastLockedOutDate = datetimeutc;
                }
            }
            else if( member.FailedPasswordAttemptCount > 0 | member.FailedPasswordAnswerAttemptCount > 0 )
            {
                member.FailedPasswordAttemptCount = 0;
                member.FailedPasswordAttemptWindowStart = DateTime.MinValue;
                member.FailedPasswordAnswerAttemptCount = 0;
                member.FailedPasswordAnswerAttemptWindowStart = DateTime.MinValue;
                member.LastLockedOutDate = DateTime.MinValue;
            }
            if (updateLastLoginActivityDate)
            {
                Aspnet_usersDTO.Update_LastActivityDateWithPersistance(GetUserId(username), username );
                DateTime time3 = DateTime.UtcNow;
             
                member.LastLoginDate = flag1 ? time3 : time1;
            }
            Aspnet_membershipDTO.Update(member);
         
            return flag1;

        }
        private DateTime RoundToSeconds(DateTime dt)
        {
            return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
        }
    }
}